#define VERBOSE
#ifdef VERBOSE
#define IF_VERBOSE(x) ({x;})
#else
#define IF_VERBOSE(x)
#endif



#include <SPI.h>
#include <RF24.h>
#include <RF24Network.h>
#include "S_message.h"
#include <printf.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Battery.h"


//pins for radio
const uint8_t rf_ce = 6;
const uint8_t rf_csn = 5;

//radio channel
const uint8_t radio_channel = 92;

//LED indication
const uint8_t led_indicator = 9;

//DS18B20 pin and temp precision
const uint8_t one_wire = 8;
const uint8_t temp_precision = 9;

//we will force reportinng every time 'cycle' reaches 'report_cycles'
const uint16_t report_cycles = 100; // 1 hour
uint16_t cycle = 0;

const unsigned long scan_timeout = 60000;
unsigned long scan_timer;


OneWire oneWire(one_wire);
DallasTemperature tempSensors(&oneWire);
DeviceAddress tempDeviceAddress;



RF24 radio (rf_ce, rf_csn);
RF24Network network (radio);
RF24NetworkHeader header(/*to node*/ 0, /*type*/ 'S'); //header for the send message
S_message message;
S_message refMessage;
const uint16_t my_address = 2;
uint8_t defMask; 


bool ok;



void setup(){
  IF_VERBOSE(Serial.begin(57600));
  IF_VERBOSE(Serial.println("Start..."));
  IF_VERBOSE(printf_begin());
  
  
  radio.begin();
  network.begin (radio_channel, my_address);
  tempSensors.begin();
  
  //define the default message mask to activate reporting of the respective sensors
  defMask = 0;
  bitSet(defMask, S_MASK_BATTERY);
  bitSet(defMask, S_MASK_TEMP);
  
  pinMode(led_indicator, OUTPUT);
}


void loop(){
  

  
  // Pump the network regularly
  network.update();
  
  if (millis() > scan_timer){
   
    scan_timer = millis()+scan_timeout;
   
    cycle++;
    message.mask = 0; 
    
    //measure temperature
    tempSensors.requestTemperatures();
    message.temp_reading = tempSensors.getTempCByIndex(0);
    if (refMessage.temp_reading != message.temp_reading)
      bitSet(message.mask, S_MASK_TEMP);
    message.battery_reading = 0;
    
    //reading battery Vcc
    message.battery_reading = Battery.readVcc();
    if (refMessage.battery_reading != message.battery_reading)
      bitSet(message.mask, S_MASK_BATTERY);
      
    if (cycle>report_cycles){
      message.mask = defMask; //force report
      cycle = 0; //reset timer
    }
    
    
    if (message.mask){
      IF_VERBOSE(printf("%lu:cycle %u, sending %s", millis(), cycle, message.toString()));
      
      ok=network.write(header,&message,sizeof(message));
      if (!ok){
        ok =  network.write(header,&message,sizeof(message));
      }
      
      if (ok) {
        IF_VERBOSE(printf("...OK\n"));
        refMessage = message;
        digitalWrite(led_indicator, HIGH);
      }
      else{
        IF_VERBOSE(printf("...NOK\n"));
        digitalWrite(led_indicator, LOW);
        //as sending measurements during this force_report cycle failed, 
        //make sure next cycle is again force_report
        if (message.mask == defMask) cycle = report_cycles;
      }      
    }
 }
  
}

